package com.groupbuying.redpacket.service.impl;

import com.alibaba.fastjson.JSON;
import com.groupbuying.redpacket.bo.RedPacketLimitBO;
import com.groupbuying.redpacket.constants.LargeScreenConstants;
import com.groupbuying.redpacket.constants.RedisConstans;
import com.groupbuying.redpacket.constants.TimerTaskConstants;
import com.groupbuying.redpacket.dao.RedPacketTaskDao;
import com.groupbuying.redpacket.domain.RedPacketTaskDO;
import com.groupbuying.redpacket.service.DelayTimerService;
import com.groupbuying.redpacket.service.HandleRedPacketTaskService;
import com.groupbuying.redpacket.utils.RedisUtils;
import com.groupbuying.redpacket.utils.SpringConfigTool;
import com.groupbuying.redpacket.utils.apiresult.ApiResult;
import com.groupbuying.redpacket.utils.apiresult.ApiResultCode;
import com.groupbuying.redpacket.websocket.LargeScreenWebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @ClassName DelayTimerServiceImpl
 * @Description: TODO   延时定时任务业务实现类
 * @Author srlg3
 * @Date 2019/11/27
 * @Version V1.0
 **/
@Service
public class DelayTimerServiceImpl implements DelayTimerService {

    Logger logger = LoggerFactory.getLogger(DelayTimerServiceImpl.class);

    private Timer timer = null;

    @Autowired
    private RedPacketTaskDao redPacketTaskDao;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public ApiResult timerControl(String taskId){

        //1. 查询是否有定时任务正在执行
        if (redisUtils.isHasKey(RedisConstans.RED_PACKAGE_HAS_TIMER)) {
            logger.error("已存在定时任务,退出");
            return ApiResult.failure("有任务正在进行中");
        }

        //获取任务持续时间
        RedPacketTaskDO redPacketTaskDO = redPacketTaskDao.get(Long.parseLong(taskId));

        if (redPacketTaskDO == null) {
            logger.error("执行延时任务,任务id:{},错误提示：红包任务信息查询为空",taskId);
            return ApiResult.failure("红包任务信息查询为空");
        }

        boolean ret = redisUtils.setIfAbsent(RedisConstans.RED_PACKAGE_HAS_TIMER, 1, redPacketTaskDO.getKeepTime() + LargeScreenConstants.LARGE_SCREEN_SETTLE_PAGE_TIME);

        if (!ret) {
            logger.error("已存在定时任务,退出");
            return ApiResult.failure("已存在定时任务,退出任务启动");
        }
        //2. 发送socket
        try {
            Map<String,String> retMap = new HashMap<>();
            retMap.put(LargeScreenConstants.LARGE_SCREEN_PUSH_SOCKET_FIELD_LIMIT,"");
            retMap.put(LargeScreenConstants.LARGE_SCREEN_PUSH_SOCKET_FIELD_STATE,LargeScreenConstants.LARGE_SCREEN_PUSH_SOCKET_STATE_TIME_START);

            LargeScreenWebSocketServer.sendInfo(JSON.toJSONString(ApiResult.success(ApiResultCode.SUCCESS,retMap)));
        } catch (Exception e) {
            logger.error("webSocket发送失败");
            e.printStackTrace();
        }

        //3. 启动定时任务
        timer = new Timer();

        timer.schedule(new TimerTask() {

            //控制是否执行过开始程序
            boolean isExecuteStart = false;
            //控制是否有任务正在执行
            boolean lock = false;

            long startTime = System.currentTimeMillis();
            @Override
            public void run() {

                logger.info("当前定时任务执行时间：{}",(System.currentTimeMillis() - startTime)/1000);

                HandleRedPacketTaskService handleRedPacketTaskService = null;

                //当前系统时间和启动时间时间差
                long subTime = (System.currentTimeMillis() - startTime)/1000;

                //1. 延迟执行开始
                if (subTime >= TimerTaskConstants.TIMEING_START_TIME_SEC && !isExecuteStart && !lock) {
                    logger.info("正在执行开始任务-----------------");
                    lock = true;

                    //获取操作红包任务
                    handleRedPacketTaskService = SpringConfigTool.getBean(HandleRedPacketTaskService.class);

                    //执行任务开始
                    boolean ret = handleRedPacketTaskService.taskStart(taskId);

                    //启动任务失败直接退出定时任务
                    if (!ret) {
                        logger.error("提示信息：启动红包任务失败异常,退出定时任务");
                        redisUtils.delKey(RedisConstans.RED_PACKAGE_HAS_TIMER);
                        //关闭红包任务
                        this.cancel();
                        return;
                    }

                    isExecuteStart = true;
                    lock = false;
                }

                //2. 定时执行关闭
                if (isExecuteStart && !lock) {

                    //开启锁
                    lock = true;
                    //持续时间+倒计时（计数时间）
                    RedPacketLimitBO redPacketLimitBO = (RedPacketLimitBO) redisUtils.getValue(RedisConstans.RED_PACKAGE_CONTROL);
                    int regTime = redPacketLimitBO.getKeepTime() + TimerTaskConstants.TIMEING_START_TIME_SEC;
                    //定时关闭定时任务  加上计数秒数
                    if (subTime >= regTime) {
                        logger.info("正在执行任务关闭-----------------");
                        //获取操作红包任务
                        handleRedPacketTaskService = SpringConfigTool.getBean(HandleRedPacketTaskService.class);

                        //关闭红包任务
                        boolean ret = handleRedPacketTaskService.taskFinish(taskId);

                        //红包成功关闭进行关闭否则继续执行
                        if (ret) {
                            logger.error("提示信息：红包关闭成功关闭定时任务");
                            redisUtils.delKey(RedisConstans.RED_PACKAGE_HAS_TIMER);
                            //关闭红包任务
                            this.cancel();
                        }
                    }
                    //关闭锁
                    lock = false;
                }
            }
        }, TimerTaskConstants.DELATY_START_TIME_SEC*1000, TimerTaskConstants.INTERVAL_START_TIME_SEC*1000);

        return ApiResult.success();

    }
}
